package top.lyjwn.todo.aop.permission;

import com.alibaba.fastjson2.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.lyjwn.todo.aop.permission.lang.PermissionException;
import top.lyjwn.todo.aop.token.ExemptToken;
import top.lyjwn.todo.common.template.R;

import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 〈权限验证切面〉<br>
 * 〈使用权限验证切面的项目必须要实现PermissionVerifyHandle，可不做操作，但必须要实现〉
 *
 * @author luoyujie
 */
@Component
@Aspect
public class PermissionVerifyAspect {


    private static final Logger LOGGER = LoggerFactory.getLogger("info");


    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired(required = false)
    private PermissionVerifyHandle permissionVerifyHandle;

    // 配置接入点,如果不知道怎么配置,可以百度一下规则
    // 指定controller的类进行切面 @Pointcut("execution(*
    // com.controller..CustomerController.*(..))||execution(*
    // com.controller.ManageController.*(..))")
    @Pointcut("!(@annotation(top.lyjwn.todo.aop.permission.ExemptPermissionVerify) || @annotation(top.lyjwn.todo.aop.token.ExemptToken) ) && (@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping))")
    private void permissionVerifyAspect() {
        LOGGER.info("PermissionVerify aop start");
    }// 定义一个切入点


    @Around("permissionVerifyAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        // 拦截的放参数类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        // 获得被拦截的方法
        Method method = msig.getMethod();
        //如果为免令牌接口，则不验证权限
        if (method.isAnnotationPresent(ExemptToken.class) && method.getAnnotation(ExemptToken.class).required()) {
            return pjp.proceed();
        } else {
            //不存在免令牌接口，开始验证是否有免权限验证接口
            if (!method.isAnnotationPresent(ExemptPermissionVerify.class) || !method.getAnnotation(ExemptPermissionVerify.class).required()) {
                //不存在免权限验证接口，开始验证其权限
                if (permissionVerifyHandle != null) {
                    if (permissionVerifyHandle.verify(httpServletRequest.getRequestURI())) {
                        return pjp.proceed();
                    } else {
                        throw PermissionException.FAIL(403, "您没有这个权限");
                    }
                } else {
                    return pjp.proceed();
                }
            } else {
                return pjp.proceed();
            }
        }

    }
}
